package com.ruoyi.web.controller.dashboard;

import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysDictData;
import com.ruoyi.system.domain.vo.NumCountResponse;
import com.ruoyi.system.domain.vo.PayAmountWeekResponse;
import com.ruoyi.system.domain.vo.PayDayInfo;
import com.ruoyi.system.domain.vo.request.BaseRequest;
import com.ruoyi.system.mapper.GiftBookMapper;
import com.ruoyi.system.service.ISysDictTypeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@RequestMapping("/dashboard")
@RestController
public class DashboardController {

    @Autowired
    private GiftBookMapper bookMapper;

    @Autowired
    private ISysDictTypeService dictTypeService;


    /**
     *  一周收入统计
     * @return
     */
    @GetMapping("/payAmountWeek")
    public AjaxResult payAmountWeek() {
        LocalDate endDate = LocalDate.now();
        LocalDate startDate = endDate.minusDays(6);
        List<PayDayInfo> resultInfos = getPayDayInfos(startDate, endDate);

        PayAmountWeekResponse payAmountWeekResponse = new PayAmountWeekResponse();
        payAmountWeekResponse.setDateArray(resultInfos);
        payAmountWeekResponse.setTodayAmount(resultInfos.get(resultInfos.size() - 1).getPayAmount());
        payAmountWeekResponse.setTodayPayCount(resultInfos.get(resultInfos.size() - 1).getPayCount());
        payAmountWeekResponse.setYesterdayAmount(resultInfos.get(resultInfos.size() - 2).getPayAmount());
        payAmountWeekResponse.setPayWeek(resultInfos.stream().map(PayDayInfo::getPayAmount).reduce(BigDecimal.ZERO, BigDecimal::add));
        return AjaxResult.success(payAmountWeekResponse);
    }

    private List<PayDayInfo> getPayDayInfos(LocalDate startDate, LocalDate endDate) {
        List<PayDayInfo> payDayInfos = bookMapper.payAmountWeek(
                LocalDateTime.of(startDate, LocalTime.MIN),
                LocalDateTime.of(endDate, LocalTime.MAX)
                );
        Map<String, PayDayInfo> payDayInfoMap = payDayInfos.stream().collect(Collectors.toMap(PayDayInfo::getPayDate, v -> v));
        List<PayDayInfo> resultInfos = new ArrayList<>();
        while (!startDate.isAfter(endDate)) {
            String format = startDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
            if (payDayInfoMap.containsKey(format)) {
                resultInfos.add(payDayInfoMap.get(format));
            } else {
                resultInfos.add(new PayDayInfo(format, BigDecimal.ZERO,0));
            }
            startDate = startDate.plusDays(1);
        }
        return resultInfos;
    }


    @GetMapping("/numCount")
    public AjaxResult numCount() {
        NumCountResponse response =  bookMapper.numCount();
        String countAndAmount = response.getCountAndAmount();
        String[] split = countAndAmount.split("-");
        response.setTotalAmount(new BigDecimal(split[1]));
        response.setTotalCount(Integer.parseInt(split[0]));
        return AjaxResult.success(response);
    }


    @PostMapping("/payCount")
    public AjaxResult payCount(@RequestBody(required = false) BaseRequest request) {
        if (request == null) {
            LocalDate endDate = LocalDate.now();
            LocalDate startDate = endDate.minusDays(6);
            request = new BaseRequest();
            request.setStartDate(startDate);
            request.setEndDate(endDate);
        }

        List<PayDayInfo> payDayInfos = getPayDayInfos(request.getStartDate(), request.getEndDate());

        List<PayDayInfo> refundAmounts = new ArrayList<>(payDayInfos.size());
        for (PayDayInfo payDayInfo : payDayInfos) {
            refundAmounts.add(new PayDayInfo(payDayInfo.getPayDate(),BigDecimal.ZERO, 0));
        }

        Map<String, List<PayDayInfo>> resultMap = new HashMap<>();
        resultMap.put("pay", payDayInfos);
        resultMap.put("refund", refundAmounts);
        return AjaxResult.success(resultMap);
    }

    private static final String dictType = "gift_channel_type";

    @PostMapping("/payTypeCount")
    public AjaxResult payTypeCount(@RequestBody(required = false) BaseRequest request) {
        Integer bookId = null;
        if (request != null) {
            bookId = request.getBookId();
        }
        List<PayDayInfo> payDayInfos =bookMapper.payTypeCount(bookId);
        Map<String, PayDayInfo> payTypeMap = payDayInfos.stream().collect(Collectors.toMap(PayDayInfo::getPayDate, v -> v));
        List<SysDictData> sysDictData = dictTypeService.selectDictDataByType(dictType);

        List<PayDayInfo> resultInfos = new ArrayList<>();
        sysDictData.forEach(v -> {
            PayDayInfo payDayInfo = payTypeMap.get(v.getDictValue());
            if (payDayInfo == null) {
                payDayInfo = new PayDayInfo(v.getDictLabel(), v.getDictValue(), BigDecimal.ZERO, 0);
            } else {
                payDayInfo.setLabel(v.getDictLabel());
            }
            resultInfos.add(payDayInfo);
        });
        return AjaxResult.success(resultInfos);
    }
}
